package com.example.watchfaceanimation;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

public class NumberFlipView extends View {

    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

    private int mFlipNumber = 1990;

    private int mOutterFlipNumber = mFlipNumber;

    private Rect textRect = new Rect();

    private float mMaxMoveHeight;

    private float mCurrentMoveHeight;

    private float mOutterMoveHeight;

    private float mCurrentAlphaValue;

    // 新数字拆分成的集合
    private List<String> flipNumbers = new ArrayList<>();

    // 老数字拆分成的集合
    private List<String> flipOutterNumbers = new ArrayList<>();

    private void initFlipView(Context context) {
        paint.setColor(Color.WHITE);
        int fontSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 54, context.getResources().getDisplayMetrics());
        paint.setTextSize(fontSize);
        paint.setStyle(Paint.Style.STROKE);
        mMaxMoveHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, context.getResources().getDisplayMetrics());
    }

    public NumberFlipView(Context context) {
        super(context);
        initFlipView(context);
    }

    public NumberFlipView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initFlipView(context);
    }

    public NumberFlipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initFlipView(context);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public NumberFlipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initFlipView(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        flipNumbers.clear();
        flipOutterNumbers.clear();
        String flipNumberString = String.valueOf(mFlipNumber);
        for (int i = 0; i < flipNumberString.length(); i++) {
            flipNumbers.add(String.valueOf(flipNumberString.charAt(i)));
        }

        String flipOutterNumberString = String.valueOf(mOutterFlipNumber);
        for (int i = 0; i < flipNumberString.length(); i++) {
            flipOutterNumbers.add(String.valueOf(flipOutterNumberString.charAt(i)));
        }
        paint.getTextBounds(String.valueOf(mFlipNumber), 0, String.valueOf(mFlipNumber).length(), textRect);

        final int textWidth = textRect.width() + 80;
        float curTextWidth = 0;
        for (int i = 0; i < flipNumbers.size(); i++) {
            paint.getTextBounds(flipNumbers.get(i), 0, flipNumbers.get(i).length(), textRect);
            final int numWidth = textRect.width();
            if (flipNumbers.get(i).equals(flipOutterNumbers.get(i))) {
                //位数数字相同，直接绘制上去不做任何动画效果
                paint.setAlpha(255);

                canvas.drawText(flipNumbers.get(i), getWidth() / 2 - textWidth / 2 + curTextWidth, getHeight() / 2 + textRect.height() / 2, paint);
            } else {
                //位数数字不同，表示需要需要处理移动操作。
                paint.setAlpha((int) (255 * (1 - mCurrentAlphaValue)));
                canvas.drawText(flipOutterNumbers.get(i), getWidth() / 2 - textWidth / 2 + curTextWidth, mOutterMoveHeight + getHeight() / 2 + textRect.height() / 2, paint);
                paint.setAlpha((int) (255 * mCurrentAlphaValue));
                canvas.drawText(flipNumbers.get(i), getWidth() / 2 - textWidth / 2 + curTextWidth, mCurrentMoveHeight + getHeight() / 2 + textRect.height() / 2, paint);
            }
            curTextWidth += (numWidth + 20);
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            jumpNumber();
        }
        return super.onTouchEvent(event);
    }

    private void jumpNumber() {
        mOutterFlipNumber = mFlipNumber;
        mFlipNumber++;

        ValueAnimator animator = ValueAnimator.ofFloat(mMaxMoveHeight, 0);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurrentMoveHeight = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator.setDuration(100);
        animator.start();

        ValueAnimator animator1 = ValueAnimator.ofFloat(0, 1);
        animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurrentAlphaValue = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator1.setDuration(100);
        animator1.start();

        ValueAnimator animator2 = ValueAnimator.ofFloat(0, -mMaxMoveHeight);
        animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mOutterMoveHeight = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator2.setDuration(100);
        animator2.start();
    }
}
